import requests
from re import findall
from apscheduler.schedulers.blocking import BlockingScheduler
from json import loads

# 从文件读取配置信息
with open('settings.txt', encoding='utf-8') as f:
    settings = loads(f.read())

api_key = settings.get('api_key')  # API令牌
zone_id = settings.get('zone_id')  # 区域ID
need_ddns_list = settings.get('need_ddns_list')  # 需要DDNS的名称列表

headers = {
    'Authorization': 'Bearer ' + api_key,
    'Content-Type': 'application/json'
}


def get_host_ip():
    """获取本机公网地址"""
    response = requests.get('http://txt.go.sohu.com/ip/soip').text
    ip = findall(r'\d+.\d+.\d+.\d+', response)
    if len(ip) > 0:
        return ip[0]
    print('获取公网IP失败:{}'.format(response))
    return None


def get_dns_records():
    """
    获取DNS记录字典
    :return: DNS记录字典
    """
    response = requests.get(
        url='https://api.cloudflare.com/client/v4/zones/{}/dns_records?type=A&order=type&direction=desc&match=all'.format(
            zone_id), headers=headers).json()
    dns_dict = {}
    if response.get('result'):
        for dns in response.get('result'):
            dns_dict[dns.get('name')] = {'id': dns.get('id'), 'ip': dns.get('content'),
                                         'zone_name': dns.get('zone_name')}
        return dns_dict
    print('获取DNS记录列表失败:{}'.format(str(response)))
    return None


def create_dns_record(name, ip, ttl=1, dns_type='A'):
    """
    创建DNS记录
    :param name: 记录名称
    :param ip: 记录值(IP)
    :param ttl: 默认自动
    :param dns_type: 默认A记录
    :return: DNS记录信息
    """
    # 发送请求
    response = requests.post(url='https://api.cloudflare.com/client/v4/zones/{}/dns_records'.format(zone_id),
                             headers=headers, json={
            'type': dns_type,
            'name': name,
            'content': ip,
            'ttl': ttl
        }).json()
    # 判断结果
    if not response['success']:
        if response['errors'][0]['message'] == 'Record already exists.':
            print('记录已存在')
        else:
            print(response['errors'][0]['message'])
        return
    print(response)


def update_dns_record(record_id, name, ip, ttl=1, dns_type='A'):
    """"""
    response = requests.put('https://api.cloudflare.com/client/v4/zones/{}/dns_records/{}'.format(zone_id, record_id),
                            headers=headers, json={'type': dns_type, 'name': name, 'content': ip, 'ttl': ttl}).json()
    # 判断结果
    if not response['success']:
        print('更新DNS记录列表失败:'.format(str(response)))
    else:
        print('更新记录{} {}成功'.format(name, ip))


def run():
    # 获取该区域所有DNS A记录
    record_dict = get_dns_records()
    if not record_dict:
        return
    local_ip = get_host_ip()  # 获取本机IP地址
    domain = record_dict[list(record_dict.keys())[0]].get('zone_name')
    for dns_name in need_ddns_list:
        if dns_name == '':
            dns_domain_name = '{}'.format(domain)
        else:
            dns_domain_name = '{}.{}'.format(dns_name, domain)
        # 判断要解析的记录是否已存在 已存在则更新 不存在则先判断是否一致，不一致则更新
        if dns_domain_name not in record_dict.keys():
            create_dns_record(name=dns_name, ip=local_ip)  # 创建记录
        else:
            if local_ip != record_dict.get(dns_domain_name).get('ip'):
                update_dns_record(record_dict.get(dns_domain_name).get('id'), dns_name, ip=local_ip)  # 更新记录
            else:
                print('记录值一致，不需要更新')


if __name__ == '__main__':
    scheduler = BlockingScheduler(timezone='Asia/Shanghai')
    run()
    # 采用固定时间间隔（interval）的方式，每隔60秒钟执行一次
    scheduler.add_job(run, 'interval', seconds=60)
    scheduler.start()
